#!/usr/bin/env python

from lib import NestedRingLocator, DavManager, Replica, WriteThread, DeleteThread, DAVNS, DAVPROPS, DAVMTIMEFMT

import os, optparse, stat, time, calendar
from webdav.Connection import Connection, WebdavError
from webdav.WebdavClient import ResourceStorer


def check_data(guid, nloc, oloc=None):
    pass

def check_meta(path, nloc, oloc=None):
    nrep = Replica(nloc, path)
    missing, existing = [], {}
    prop_names = [
        (DAVNS, DAVPROPS[1]),   # getlastmodified
        (STATNS, STATPROPS[0]), # mode
    ]
    for url in nrep.urls:
        c = ResourceStorer(url)
        try:
            r = c.readProperties(*prop_names, ignore_404=True)
            mode = int(r.get((STATNS, STATPROPS[0])).textof())
            existing[calendar.timegm(time.strptime(r.get((DAVNS, DAVPROPS[1])).textof(), DAVMTIMEFMT))] = url
        except WebdavError, e:
            missing.append(url)
    mtimes = existing.keys()
    mtimes.sort()
    guid = ResourceStorer(existing[mtimes[-1]]).downloadContent().read()
    for url in missing:
        WriteThread(url, guid)
    check_data(guid, nloc, oloc)
    if stat.S_ISDIR(mode):
        d = ReplicatedDir(nloc, path)
        for child, type in d.children.items():
            check_meta(os.path.join(path, child), nloc, oloc)
    if oloc:
        orep = Replica(oloc, path)
        for url in nrep.urls:
            try:
                orep.urls.remove(url)
            except:
                pass
        for url in orep.urls:
            DeleteThread(url)


def main():
    parser = optparse.OptionParser(prog="fsck.power", description="Filesystem check tool for PoWeR FS.")
    parser.add_option("-d", "--debug", action="store_true", help="Break into python debugger.")
    parser.add_option("-c", "--config", help="The cluster configuration file.")
    parser.add_option("-p", "--previous", help="The previous cluster configuration file.")

    (options, args) = parser.parse_args()

    if not options.config:
        parser.error('Config file is required.')
    if not os.path.exists(options.config):
        parser.error('Config file \'%s\' is missing.' % options.config)
    if options.previous and not os.path.exists(options.previous):
        parser.error('Previous config file \'%s\' is missing.' % options.previous)

    if options.debug:
        import pdb; pdb.set_trace()

    globals = {}
    try:
        execfile(options.config, globals)
        nloc = NestedRingLocator(globals['nodes'])
    except:
        parser.error('Config file invalid.')

    oloc = None
    if options.previous:
        try:
            execfile(options.previous, globals)
            oloc = NestedRingLocator(globals['nodes'])
        except:
            parser.error('Previous config file invalid.')

    check_meta('/', nloc, oloc)

if __name__ == '__main__':
    main()